<template>
	<view class="gurudin-audio" :class="theme">
		<view class="gurudin-poster">
			<image :src="poster" v-if="poster != ''" class="musicRotate" :class="{ musicPaused: !audio.isPlay }"></image>
			<view class="tools" @click.native="play">
				<image :src="audio.isPlay ? icon.pause : icon.play"></image>
			</view>
		</view>
		<view class="gurudin-content">
			<view class="title">
				{{ name }}
				<view class="time">{{ formatTime(audio.startTime) }}</view>
			</view>
			<view class="author">{{ author }}</view>
		</view>
		<view @click="close" class="close">
			<u-icon name="close" color="#333"></u-icon>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'gurudin-audio',

		props: {
			/**
			 * 播放回调方法
			 */
			call: {
				type: Function
			},

			/**
			 * 封面
			 */
			poster: {
				type: String,
				default: ''
			},

			duration: {
				type: Number,
				default: 0
			},

			/**
			 * 演唱者
			 */
			author: {
				type: String,
				default: ''
			},

			/**
			 * 歌曲名称
			 */
			name: {
				type: String,
				default: ''
			},

			/**
			 * 音频链接
			 */
			src: {
				type: String,
				required: true
			},

			/**
			 * 主题
			 */
			theme: {
				type: String,
				default: 'light'
			},

			/**
			 * 是否循环播放
			 */
			loop: {
				type: Boolean,
				default: false
			},

			/**
			 * 是否遵循系统静音开关
			 */
			obeyMuteSwitch: {
				type: Boolean,
				default: true
			}
		},

		data() {
			return {
				/**
				 * icon
				 */
				icon: {
					play: '',
					pause:
						''
				},

				/**
				 * 音频播放对象
				 */
				audio: {
					/**
					 * 是否正在播放
					 * false=否 true=是
					 */
					isPlay: false,

					/**
					 * 当前播放时间
					 */
					startTime: this.duration,

					/**
					 * 音频总时长
					 */
					duration: this.duration,

					/**
					 * 播放进度
					 */
					playProgress: 0,

					/**
					 * 音频播放对象
					 */
					innerAudioContext: null
				}
			}
		},

		methods: {
			/**
			 * 格式化播放时间 00:00
			 */
			formatTime(second) {
				if (second == 0) {
					return '00:00'
				}

				let mm = Number((second / 60).toFixed(0))
				mm = mm < 10 ? '0' + mm : mm

				let ss = Number((second % 60).toFixed(0))
				ss = ss < 10 ? '0' + ss : ss

				return mm + ':' + ss
			},

			/**
			 * 播放 or 暂停
			 */
			play() {
				if (this.audio.isPlay) {
					// 暂停播放
					this.onPause()
				} else {
					// 开始播放
					if (typeof this.call == 'function') {
						this.call(this.src)
					}

					this.onPlay()
				}
			},

			/**
			 * 暂停
			 */
			onPause() {
				if (this.audio.innerAudioContext != null) {
					this.audio.isPlay = false

					this.audio.innerAudioContext.pause()
				}
			},

			/**
			 * 播放
			 */
			onPlay() {
				this.audio.isPlay = true

				if (this.audio.innerAudioContext == null) {
					this.audio.innerAudioContext = uni.createInnerAudioContext()
					this.audio.innerAudioContext.src = this.src
					this.audio.innerAudioContext.loop = this.loop
					this.audio.innerAudioContext.obeyMuteSwitch = this.obeyMuteSwitch
					this.audio.innerAudioContext.autoplay = this.autoplay
				}

				// 是否准备完成
				this.audio.innerAudioContext.onCanplay(() => {
					this.audio.duration = this.audio.innerAudioContext.duration
				})

				// 开始播放
				this.audio.innerAudioContext.play()

				// 音频播放进度更新事件
				this.audio.innerAudioContext.onTimeUpdate(() => {
					if (this.audio.duration == 0) {
						this.audio.duration = this.audio.innerAudioContext.duration
					} else {
						this.audio.playProgress = ((Number(this.audio.startTime.toFixed(2)) / this.audio.duration) * 100).toFixed(2)
					}

					this.audio.startTime = this.audio.innerAudioContext.currentTime
				})

				// 播放完成事件
				this.audio.innerAudioContext.onEnded(() => {
					this.audio.startTime = this.duration
					this.audio.playProgress = 0

					if (!this.loop) {
						this.onPause()
					}
				})

				// 音源错误
				this.audio.innerAudioContext.onError((res) => {
					this.audio.isPlay = false

					uni.showModal({
						title: '提示',
						content: '系统错误',
						showCancel: false
					})
				})
			},

			close() {
				this.$emit('delVideo')
			}
		},

		created() {}
	}
</script>

<style lang="scss">
	.light {
		border: 2rpx solid #e8eaec;
		background: #fff;

		.gurudin-poster {
			background: #dcdee2;
		}

		.gurudin-content {
			.title {
				color: #2c405a;

				.time {
					color: #808695;
				}
			}

			.author {
				color: #808695;
			}
		}
	}

	.dark {
		border: 2rpx solid #17233d;
		background: #515a6e;

		.gurudin-poster {
			background: #17233d;
		}

		.gurudin-content {
			.title {
				color: #ffffff;

				.time {
					color: #c5c8ce;
				}
			}

			.author {
				color: #c5c8ce;
			}
		}
	}

	.gurudin-audio {
		animation: mymove 0.5s;
		position: relative;
		height: 80rpx;
		border-radius: 8rpx;
		clear: both;
		.close {
			position: absolute;
			right: 16rpx;
			top: 20rpx;
			font-weight: 100;
			font-size: 27rpx;
		}

		.gurudin-poster,
		.gurudin-content {
			float: left;
		}

		.gurudin-poster {
			position: relative;
			width: 130rpx;
			height: 76rpx;
			margin-top: 1rpx;
			margin-left: 1rpx;
			border-top-left-radius: 8rpx;
			border-bottom-left-radius: 8rpx;

			image {
				width: 110rpx;
				height: 110rpx;
				margin: 10rpx;
				opacity: 0.8;
				border-radius: 100%;
			}

			.tools {
				position: absolute;
				text-align: center;
				top: 0;
				left: 0;
				height: 80rpx;
				width: 130rpx;

				image {
					width: 50rpx;
					height: 50rpx;
					margin-top: 15rpx;
				}
			}
		}

		.gurudin-content {
			width: calc(100% - 130rpx - 62rpx);
			height: 80rpx;
			padding: 0 30rpx;
			line-height: 80rpx;
			position: relative;

			.title {
				position: relative;
				font-size: 28rpx;
				height: 40rpx;

				.time {
					position: absolute;
					right: 0;
					top: 0;
					font-size: 24rpx;
				}
			}

			.author {
				margin-top: 10rpx;
				font-size: 24rpx;
			}
		}
	}

	@keyframes mymove {
		from {
			opacity: 0;
		}

		to {
			opacity: 1;
		}
	}

	// 旋转动画
	.musicRotate {
		animation: rotate 10s linear infinite;
	}

	@keyframes rotate {
		from {
			transform: rotate(0deg);
		}
		to {
			transform: rotate(359deg);
		}
	}

	.musicPaused {
		animation-play-state: paused;
	}
</style>
